package management

import (
	"context"
	"encoding/json"
	"net/http"
	"strconv"
	"time"

	"github.com/gorilla/mux"
	"github.com/jsrccb/nachuan/common"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

type ClueTraceMgr struct {
	client              *mongo.Client
	clueTraceCollection *mongo.Collection
}

var (
	G_clueTraceMgr *ClueTraceMgr
)

func initClueTraceApi(r *mux.Router) {
	s := r.PathPrefix("/cluetrace").Subrouter()
	// s.HandleFunc("/list", UserListHandler)
	s.HandleFunc("/updsave", handleClueTraceInfo)
	s.HandleFunc("/del", handleDelClueTrace)
	//请求/clue/query?clueno=xxx
	s.HandleFunc("/query", handleQueryClueTraceInfo)
}

func (clueTraceMgr *ClueTraceMgr) delClueTrace(id string) (err error) {

	_, err = clueTraceMgr.clueTraceCollection.DeleteOne(context.TODO(), bson.D{{"id", id}}, &options.DeleteOptions{})

	// fmt.Println("doccount:" + strconv.FormatInt(doccount, 10))
	return
}

func (clueTraceMgr *ClueTraceMgr) saveClueTrace(clueTrace *common.ClueTrace) (err error) {

	_, err = clueTraceMgr.clueTraceCollection.InsertOne(context.TODO(), clueTrace)

	return
}

func (clueTraceMgr *ClueTraceMgr) updClueTrace(clueTrace *common.ClueTrace) (err error) {

	_, err = clueTraceMgr.clueTraceCollection.UpdateOne(context.TODO(), bson.D{{"id", clueTrace.ID}}, bson.M{"$set": clueTrace})

	return
}

func (clueTraceMgr *ClueTraceMgr) queryClueTraceById(id string) (clueTraceInfo *common.ClueTrace, err error) {

	var (
		// resultOne *mongo.InsertOneResult
		filter *common.ClueTraceIdFilter
		result *mongo.SingleResult

		// update *common.HostInfo
	)
	// fmt.Println("clueNo:", clueNo)

	filter = &common.ClueTraceIdFilter{
		ID: id,
	}

	result = clueTraceMgr.clueTraceCollection.FindOne(context.TODO(), filter, &options.FindOneOptions{})
	result.Decode(&clueTraceInfo)
	// fmt.Println("clueInfo:", clueInfo)
	return
}

func (clueTraceMgr *ClueTraceMgr) queryClueTracebyClueNo(clueNo string, skip int64, limit int64) (clueTraceInfo []*common.ClueTrace, err error) {

	var (
		// resultOne *mongo.InsertOneResult
		cursor        *mongo.Cursor
		cluetraceinfo *common.ClueTrace
		findopt       *options.FindOptions
		ctx           context.Context
		filter        *common.ClueIdFilter
		clueSort      *common.SortLogByClueNo
		// update *common.HostInfo
	)

	ctx, _ = context.WithTimeout(context.Background(), 10*time.Second)

	findopt = &options.FindOptions{}
	clueSort = &common.SortLogByClueNo{
		SortOrder: -1,
	}
	findopt.SetSort(clueSort)
	if limit > 0 && skip >= 0 {
		findopt.SetLimit(limit)
		findopt.SetSkip(limit * skip)

	} else {
		return
	}

	filter = &common.ClueIdFilter{
		ClueNo: clueNo,
	}

	// fmt.Println(setElements)
	// fmt.Println(setElements.Map())
	cursor, err = clueTraceMgr.clueTraceCollection.Find(context.TODO(), filter, findopt)

	defer cursor.Close(ctx)

	for cursor.Next(ctx) {
		cluetraceinfo = &common.ClueTrace{}
		if err = cursor.Decode(cluetraceinfo); err != nil {
			continue
		}
		clueTraceInfo = append(clueTraceInfo, cluetraceinfo)
	}
	// fmt.Println("doccount:" + strconv.FormatInt(doccount, 10))
	return
}

func handleQueryClueTraceInfo(resp http.ResponseWriter, req *http.Request) {
	var (
		err           error
		bytes         []byte
		clueNo        string
		cluetraceinfo []*common.ClueTrace
		skipParam     string
		limitParam    string
		skip          int
		limit         int
		// rolelimit     *common.RoleLimits
	)

	query := req.URL.Query()
	clueNo = query.Get("clueno")
	skipParam = query.Get("skip")
	limitParam = query.Get("limit")

	if skip, err = strconv.Atoi(skipParam); err != nil {
		skip = 0
	}

	if limit, err = strconv.Atoi(limitParam); err != nil {
		limit = 100
	}

	if clueNo != "" {
		cluetraceinfo, _ = G_clueTraceMgr.queryClueTracebyClueNo(clueNo, int64(skip), int64(limit))
		if bytes, err = common.BuildResponse(0, "success", cluetraceinfo); err == nil {
			resp.Write(bytes)
		} else {
			goto ERR
		}
		return
	}
	return
ERR:
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

func handleDelClueTrace(resp http.ResponseWriter, req *http.Request) {
	var (
		err   error
		bytes []byte
		id    string

		// rolelimit     *common.RoleLimits
	)

	query := req.URL.Query()
	id = query.Get("id")
	// fmt.Println(clueNo)

	// fmt.Println(clueinfo)
	if err = G_clueTraceMgr.delClueTrace(id); err == nil {
		if bytes, err = common.BuildResponse(0, "success", "删除线索追踪成功"); err == nil {
			resp.Write(bytes)
		}
	} else {
		goto ERR
	}
	return
ERR:
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

func handleClueTraceInfo(resp http.ResponseWriter, req *http.Request) {
	var (
		err           error
		bytes         []byte
		clueTraceinfo *common.ClueTrace
		cluetracestr  string
		// rolelimit     *common.RoleLimits
	)

	if err = req.ParseForm(); err != nil {
		goto ERR
	}
	cluetracestr = req.PostForm.Get("cluetraceinfo")
	if err = json.Unmarshal([]byte(cluetracestr), &clueTraceinfo); err != nil {
		goto ERR
	}

	if clueTraceinfo.CreateTime == "" {
		clueTraceinfo.CreateTime = common.BuildTimeNowStr()
	}

	if clueTraceinfo.ID == "" {
		clueTraceinfo.ID = common.BuildUUID()
		if err = G_clueTraceMgr.saveClueTrace(clueTraceinfo); err == nil {
			//修改线索信息
			if clueTraceinfo.ClueNo != "" {
				clueupdinfo := &common.TraceUpdClue{
					ClueNo:        clueTraceinfo.ClueNo,
					ClueType:      clueTraceinfo.ClueType,
					ClueStatus:    clueTraceinfo.ClueStatus,
					NextTraceDate: clueTraceinfo.NextTraceDate,
					DropInfo:      clueTraceinfo.DropInfo,
					TraceDate:     common.BuildTimeNowStr(),
					TraceInfo:     clueTraceinfo.TraceInfo,
					DropReason:    clueTraceinfo.DropReason,
					CustomMgr:     clueTraceinfo.CustomMgr,
					Dept:          clueTraceinfo.Dept,
				}

				G_clueMgr.updClue(clueupdinfo)
			}
			//return
			if bytes, err = common.BuildResponse(0, "success", clueTraceinfo); err == nil {
				resp.Write(bytes)
			}
		} else {
			if bytes, err = common.BuildResponse(-1, err.Error(), "新增线索跟踪异常"); err == nil {
				resp.Write(bytes)
			}
		}
	} else {
		if err = G_clueTraceMgr.updClueTrace(clueTraceinfo); err == nil {
			if bytes, err = common.BuildResponse(0, "success", clueTraceinfo); err == nil {
				resp.Write(bytes)
			}
		} else {
			if bytes, err = common.BuildResponse(-1, err.Error(), "修改线索跟踪异常"); err == nil {
				resp.Write(bytes)
			}
		}
	}
	return
ERR:
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

func InitClueTraceMgr() (err error) {

	G_clueTraceMgr = &ClueTraceMgr{
		client:              G_MongoMgr.client,
		clueTraceCollection: G_MongoMgr.MongdbConnect.Collection("cluetrace"),
	}

	// fmt.Println("init userMgr")

	return

}
